local blaze = require "blaze"
local app = require "app"

local GameObject = CS.UnityEngine.GameObject
local LineRenderer = CS.UnityEngine.LineRenderer
local Vector3 = CS.UnityEngine.Vector3
local type_material = typeof(CS.UnityEngine.Material)
local ShadowCastingMode = CS.UnityEngine.Rendering.ShadowCastingMode
local log = blaze.logging.get("line")

local line = 
{
    
}

local drawers = {};

local mat_map = {}

local mat_names = 
{
    [1] = "line_lightblue";
    [2] = "line_lightgreen";
    [3] = "line_pink";
    [4] = "line_yellow";
}

local mat_index = 0;

local function get_material(name)
    if mat_map[name] then
        return mat_map[name];
    end

    local opt = {sync = true};
    local isOk, mat = app.res.load(string.format("club.threecard.slotlib/ui/common.b:%s:%s", name, type_material.AssemblyQualifiedName), opt);
    if isOk then
        mat_map[name] = mat;
    end

    return mat_map[name];
end

local function get_next_material()
    local i = (mat_index % #mat_names) + 1;
    local name = mat_names[i];
    mat_index = mat_index + 1;
    return get_material(name);
end

local function getDrawer()
    local obj = GameObject("drawer");
    obj.layer = CS.UnityEngine.LayerMask.NameToLayer("UI");
    local drawer = obj:AddComponent(typeof(LineRenderer));
    drawer.material = get_next_material();
    drawer.shadowCastingMode = ShadowCastingMode.Off;
    drawer.receiveShadows = false;
    drawer.allowOcclusionWhenDynamic = false;
    return drawer;
end

function line.draw(elements)
    local drawer = getDrawer();
    local pos = {};

    for index, element in ipairs(elements) do
        if element.transform then
            local p = Vector3(element.transform.position.x, element.transform.position.y, element.transform.position.z-0.1);

            if index == 1 then
                local local_p = Vector3(element.rect_transform.rect.x, element.rect_transform.rect.y, element.transform.position.z-0.1);
                local world_p = element.transform.localToWorldMatrix:MultiplyPoint(local_p);
                table.insert(pos, Vector3(world_p.x, p.y, p.z));
            end

            table.insert(pos, p);

            if index == #elements then
                local local_p = Vector3(element.rect_transform.rect.xMax, element.rect_transform.rect.y, element.transform.position.z-0.1);
                local world_p = element.transform.localToWorldMatrix:MultiplyPoint(local_p);
                table.insert(pos, Vector3(world_p.x, p.y, p.z));
            end
        elseif element.loaded then
            log.error(string.format("invalid element.transform:%s", blaze.dump(element)));
        else
            log.warn("trying to draw an element witch is not loaded");
        end
    end

    drawer.positionCount = #pos;
    drawer.startWidth = 0.06;
    drawer.endWidth = 0.06;
    drawer:SetPositions(pos);

    table.insert(drawers, drawer);

    return drawer;
end

function line.clear()
    if #drawers == 0 then
        return;
    end
    
    for _, drawer in pairs(drawers) do
        GameObject.Destroy(drawer.gameObject);
    end
    drawers = {};
end

function line.init()
    
end

function line.release()
    line.clear();

    for name, mat in pairs(mat_map) do
        local uri = string.format("club.threecard.slotlib/ui/common.b:%s:%s", name, type_material.AssemblyQualifiedName)
        app.res.unload(uri);
        mat_map[name] = nil;
    end
end

return line